package com.crm.crm.controller;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.crm.crm.annotation.Log;
import com.crm.crm.domain.Clue;
import com.crm.crm.domain.role.SysRole;
import com.crm.crm.domain.SysUser;
import com.crm.crm.domain.dto.*;
import com.crm.crm.domain.vo.PageResult;
import com.crm.crm.domain.vo.UserExcelVo;
import com.crm.crm.domain.vo.UserVo;
import com.crm.crm.domain.vo.business.result.Result;
import com.crm.crm.domain.vo.business.result.TableDataInfo;
import com.crm.crm.mapper.BusinessMapper;
import com.crm.crm.mapper.ClueMapper;
import com.crm.crm.mapper.UserRoleMapper;
import com.crm.crm.service.*;
import com.crm.crm.service.UserRoleService;
import com.crm.crm.service.UserService;
import com.crm.crm.service.impl.DeptServicelmpl;
import com.crm.crm.util.ExcelWriter;
import com.crm.crm.util.UserThreadLocalUtil;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.User;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.OutputStream;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.crm.crm.util.ExcelReader.*;

@RestController
@RequestMapping("/system/user")
@Slf4j
public class UserController {
    @Autowired
    private UserService userService;
    @Autowired
    private UserRoleService userRoleService;
    @Autowired
    private DeptServicelmpl deptServicelmpl;
    @Autowired
    private ClueService clueService;
    @Autowired
    private BusinessService businessService;

    //根据部门ID查询员工表用户名和ID
    @GetMapping("/listselect")
    public Result<List<SysUser>> getOwner(Integer deptId) {
        List<SysUser> users = userService.getOwner(deptId);
        return Result.success(users);
    }
    //用户分页查询PageResult
    @GetMapping("/list")
    public Result PageQuery(UserPageQueryParam userPageQueryParams, @RequestParam Map<String,String>params){
        userPageQueryParams.setBeginTime(params.get("params[beginTime]"));
        userPageQueryParams.setEndTime(params.get("params[endTime]"));
        TableDataInfo<UserVo> pageResult = userService.pageQuery(userPageQueryParams);
    return Result.success().put("total",pageResult.getTotal()).put("rows",pageResult.getRows());
    }
    //查询角色列表
    @GetMapping("/")
    public Result getUserList(){
        List<SysRole> sysRoles = userService.findAllRoles();
        return Result.success().put("roles",sysRoles);
    }
    //新增用户
    @Log("新增用户")
    @PostMapping
    public Result addUser(@RequestBody SysUserDto sysUserDto){
        SysUser sysUser = new SysUser();
        BeanUtil.copyProperties(sysUserDto,sysUser);
        sysUser.setCreateBy(UserThreadLocalUtil.getCurrentUserName());
        sysUser.setCreateTime(LocalDateTime.now());
        sysUser.setUpdateBy(UserThreadLocalUtil.getCurrentUserName());
        sysUser.setUpdateTime(LocalDateTime.now());
        sysUser.setDelFlag("0");
        String userName = sysUserDto.getUserName();
        Long clueNum =clueService.selectOwner(userName);

        userService.save(sysUser);
        Long userId = sysUser.getUserId();
        userService.saveBatchRoleIds(userId,sysUserDto.getRoleIds());
        return Result.success();
    }
    //根据id查询用户
    @GetMapping("/{id}")
    public Result getUserById(@PathVariable Integer id){
        SysUser sysUser = userService.getById(id);
        //获取角色id
        List<Long>roleIds= userService.selectRoleIds(id);
        //获取角色
        if (roleIds == null || roleIds.isEmpty()) {
            UserVo userVo = new UserVo();
            BeanUtil.copyProperties(sysUser, userVo);
            userVo.setDept(deptServicelmpl.selectById(sysUser.getDeptId()));
            List<SysRole> roles = userRoleService.list();
            return Result.success().put("roleIds", roleIds).put("data", userVo).put("roles", roles);
        }
        UserVo userVo = new UserVo();
        BeanUtil.copyProperties(sysUser,userVo);
        List<SysRole> sysRoles = userRoleService.listByIds(roleIds);
        userVo.setRoles(sysRoles);
        userVo.setDept(deptServicelmpl.selectById(sysUser.getDeptId()));
        //获取所有角色
        List<SysRole> roles = userRoleService.list();
        //TODO:postIds 和 posts 还没返回
        return Result.success().put("roleIds",roleIds).put("data",userVo).put("roles",roles);
    }
    //修改用户
    //TODO:归属部门修改 有问题 需要修改
    @Log("修改用户")
    @PutMapping
    public Result updateUser(@RequestBody UserVo userVo){
        SysUser sysUser = new SysUser();
        BeanUtil.copyProperties(userVo,sysUser);
        userService.updateById(sysUser);
        List<Long> roleIds = userVo.getRoleIds();
        Long userId = userVo.getUserId();
        userService.deleteRoleIds(userId);
        userService.saveBatchRoleIds(userId,roleIds);
        return Result.success();
    }
    //修改状态
    @Log("修改状态")
    @PutMapping("/changeStatus")
    public  Result changeStatus(@RequestBody UserStatusDto userStatusDto){
        userService.changeStatus(userStatusDto);
        return Result.success();
    }
    //删除用户
    @Log("删除用户")
    @DeleteMapping("/{id}")
    public Result deleteUser(@PathVariable List<Long> id){
        for (Long l : id) {
            userService.removeById(l);
            userService.deleteRoleIds(l);
        }

        return Result.success();
    }
    //重置密码
    @Log("重置密码")
    @PutMapping("/resetPwd")
    public Result resetPwd(@RequestBody UserPassWordDTO userPassWordDTO){
        String password = userPassWordDTO.getPassword();
        Long userId = userPassWordDTO.getUserId();
        userService.resetPwd(password,userId);
        return Result.success();
    }
    /**
     * 读取Excel文件内容
     *
     * @param file 上传的Excel文件
     * @return 读取结果列表，读取失败时返回null
     */
    @PostMapping("/importData")
    @Transactional
    public Result readExcel(@RequestParam MultipartFile file,Boolean updateSupport) {

        Workbook workbook = null;

        try {
            // 获取Excel后缀名
            String fileName = file.getOriginalFilename();
            if (fileName == null || fileName.isEmpty() || fileName.lastIndexOf(".") < 0) {
                log.info("解析Excel失败，因为获取到的Excel文件名非法！");
                return null;
            }
            String fileType = fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length());

            // 获取Excel工作簿
            workbook = getWorkbook(file.getInputStream(), fileType);

            // 读取excel中的数据
            List<UserVo> resultDataList = parseUserExcel(workbook);
        if ( updateSupport ==false){
            resultDataList.forEach(userVo -> {
                //存user
                SysUser sysUser = new SysUser();
                BeanUtil.copyProperties(userVo, sysUser);
                userService.save(sysUser);
                //存角色ids
                Long userId = sysUser.getUserId();
                userService.deleteRoleIds(sysUser.getUserId());
                List<Long> roleIds = new ArrayList<>();
                String[] split = userVo.getExcelRoleIds().split(",");
                for (int i = 0; i < split.length; i++) {
                    roleIds.add(Long.valueOf(split[i]));
                }
                userService.saveBatchRoleIds(userId, roleIds);
            });
        }else {
            resultDataList.forEach(userVo -> {
                //存user
                SysUser sysUser = new SysUser();
                BeanUtil.copyProperties(userVo, sysUser);
                userService.saveOrUpdate(sysUser);
                //存角色ids
                Long userId = sysUser.getUserId();
                userService.deleteRoleIds(sysUser.getUserId());
                List<Long> roleIds = new ArrayList<>();
                String[] split = userVo.getExcelRoleIds().split(",");
                for (int i = 0; i < split.length; i++) {
                    roleIds.add(Long.valueOf(split[i]));
                }
                userService.saveBatchRoleIds(userId, roleIds);
            });
        }
            return Result.success();
        } catch (Exception e) {
            log.info("解析Excel失败，文件名：" + file.getOriginalFilename() + " 错误信息：" + e.getMessage());
            return null;
        } finally {
            try {
                if (null != workbook) {
                    workbook.close();
                }
            } catch (Exception e) {
                log.info("关闭数据流出错！错误信息：" + e.getMessage());
                return null;
            }
        }
    }
    @GetMapping("/export")
    public void exportExcel(HttpServletRequest request, HttpServletResponse response,UserPageQueryParam userPageQueryParam) {
        Workbook workbook = null;
        OutputStream out = null;
        try {
            // todo 根据业务需求获取需要写入Excel的数据列表 dataList

            List<UserExcelVo> dataList = userService.getExcelData(userPageQueryParam);
            // 生成Excel工作簿对象并写入数据
            workbook = ExcelWriter.exportData(dataList);

            // 写入Excel文件到前端
            if(null != workbook){
                String excelName = "示例Excel导出";
                String fileName = excelName + DateUtil.format(new Date(), "yyyyMMdd") + ".xlsx";
                fileName = new String(fileName.getBytes("UTF-8"),"iso8859-1");
                response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
                response.setContentType("application/x-download");
                response.setCharacterEncoding("UTF-8");
                response.addHeader("Pargam", "no-cache");
                response.addHeader("Cache-Control", "no-cache");
                response.flushBuffer();
                out = response.getOutputStream();
                workbook.write(out);
                out.flush();
            }
        } catch (Exception e) {
            log.info("写入Excel过程出错！错误原因：" + e.getMessage());
        } finally {
            try {
                if (null != workbook) {
                    workbook.close();
                }
                if (null != out) {
                    out.close();
                }
            } catch (IOException e) {
                log.info("关闭workbook或outputStream出错！");
            }
        }
    }
}
